﻿using System;
using System.Data;
using System.Data.Common;
using SS.Common.Logging;

namespace SS.Common.DBBuilder.DBInteraction
{
    /// <summary>
    /// The abstract class implement interface is used to provide the means to get data from database
    /// </summary>
    public abstract class AbstractDataProvider : IDataProvider
    {
        #region Properties

        /// <summary>
        /// Data source
        /// </summary>
        public string DataSource { get; set; }

        /// <summary>
        /// Database name
        /// </summary>
        public string DataBaseName { get; set; }

        /// <summary>
        /// Store SQL command
        /// </summary>
        public string Query { get; set; }

        /// <summary>
        /// Keep connection to database
        /// </summary>
        public DbConnection ObjConnection { get; set; }

        /// <summary>
        /// Object Command to execute update data
        /// </summary>
        public DbCommand ObjCommand { get; set; }

        /// <summary>
        /// A set of SqlCommand
        /// </summary>
        public DbDataAdapter ObjDataAdapter { get; set; }

        /// <summary>
        /// The logger instance
        /// </summary>
        protected static readonly ILogger Logger = LoggerManager.GetLogger(typeof(AbstractDataProvider).Name);

        #endregion

        #region Implementation of IDataProvider

        /// <summary>
        /// Fill data from database to dataset
        /// </summary>
        /// <param name="ds">DataSet contains returned data from DB</param>
        /// <param name="tblName">Identifier table name in dataset</param>
        public void FillDataSet(ref DataSet ds, string tblName)
        {
            try
            {
                Logger.Info("FillDataSet --> Start");
                Logger.InfoFormat("Table: {0}", tblName);

                InitializeCommand();
                InitializeDataAdapter();
                this.ObjDataAdapter.Fill(ds, tblName);

                Logger.Info("FillDataSet <-- End");
            }
            catch (Exception ex)
            {
                Logger.ErrorFormat("FillDataSet: {0}", ex.ToString());
                throw new Exception(ex.ToString());
            }
            finally
            {
                this.ObjCommand.Dispose();
                this.ObjCommand = null;
                this.ObjDataAdapter.Dispose();
                this.ObjDataAdapter = null;
            }
        }

        #endregion

        #region Help methods

        /// <summary>
        /// Initialize sql command
        /// </summary>
        protected abstract void InitializeCommand();

        /// <summary>
        /// Initialize a set of command
        /// </summary>
        protected abstract void InitializeDataAdapter();

        #endregion
    }
}
